home *** CD-ROM | disk | FTP | other *** search
/ GFX Sensations 1 / Graphic Sensations - Volume 1.iso / tools / amiga / 3d_tools / irit40s.lha / Irit / cagd_lib / cagdbsum.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-01-02  |  5.9 KB  |  157 lines

  1. /******************************************************************************
  2. * CagdBSum.c - Boolean sum surface constructor out of given four curves.      *
  3. *******************************************************************************
  4. * Written by Gershon Elber, Sep. 91.                          *
  5. ******************************************************************************/
  6.  
  7. #include "cagd_loc.h"
  8.  
  9. /******************************************************************************
  10. * Constructs a boolean sum surface using the four provided boundary curves.   *
  11. * Curve end points must meet at the corners if surface boundary should be the *
  12. * same as the four curves.                              *
  13. ******************************************************************************/
  14. CagdSrfStruct *CagdBoolSumSrf(CagdCrvStruct *CrvLeft,
  15.                   CagdCrvStruct *CrvRight,
  16.                   CagdCrvStruct *CrvTop,
  17.                   CagdCrvStruct *CrvBottom)
  18. {
  19.     int i, j;
  20.     CagdCrvStruct *Crv1, *Crv2;
  21.     CagdSrfStruct *Ruled1, *Ruled2, *Ruled3, *Srf;
  22.     CagdPtStruct Pt1, Pt2;
  23.     CagdRType **SrfPoints, **Ruled1Pts, **Ruled2Pts, **Ruled3Pts;
  24.  
  25.     CrvLeft = CagdCrvCopy(CrvLeft);
  26.     CrvRight = CagdCrvCopy(CrvRight);
  27.     CrvTop = CagdCrvCopy(CrvTop);
  28.     CrvBottom = CagdCrvCopy(CrvBottom);
  29.  
  30.     /* The Left-Right and Top-Bottom curves should share same point/curve    */
  31.     /* type as well as same order and knot vector (if Bspline representation)*/
  32.     CagdMakeCrvsCompatible(&CrvLeft, &CrvRight, TRUE, TRUE);
  33.     CagdMakeCrvsCompatible(&CrvTop, &CrvBottom, TRUE, TRUE);
  34.  
  35.     /* The Left-Right and Top-Bottom pairs must share same point/curve type. */
  36.     CagdMakeCrvsCompatible(&CrvLeft, &CrvTop, FALSE, FALSE);
  37.     CagdMakeCrvsCompatible(&CrvLeft, &CrvBottom, FALSE, FALSE);
  38.     CagdMakeCrvsCompatible(&CrvRight, &CrvTop, FALSE, FALSE);
  39.     CagdMakeCrvsCompatible(&CrvRight, &CrvBottom, FALSE, FALSE);
  40.  
  41.     /* Now that the curves are in the right representation, form surface(s). */
  42.     /* The two ruled surface between the respective curves, in right orders: */
  43.     Ruled1 = CagdRuledSrf(CrvLeft, CrvRight,
  44.               CrvTop -> Order, CrvTop -> Length);
  45.     Ruled2 = CagdRuledSrf(CrvTop, CrvBottom,
  46.               CrvRight -> Order, CrvRight -> Length);
  47.     Srf = CagdSrfReverse2(Ruled2);
  48.     CagdSrfFree(Ruled2);
  49.     Ruled2 = Srf;
  50.  
  51.     /* The ruled surface between the four corner points in the right orders. */
  52.     CagdCoerceToE3(Pt1.Pt, CrvLeft -> Points, 0, CrvLeft -> PType);
  53.     CagdCoerceToE3(Pt2.Pt, CrvLeft -> Points, CrvLeft -> Length - 1,
  54.                             CrvLeft -> PType);
  55.     Crv1 = CagdMergePtPt(&Pt1, &Pt2);
  56.  
  57.     CagdCoerceToE3(Pt1.Pt, CrvRight -> Points, 0, CrvRight -> PType);
  58.     CagdCoerceToE3(Pt2.Pt, CrvRight -> Points, CrvRight -> Length - 1,
  59.                             CrvRight -> PType);
  60.     Crv2 = CagdMergePtPt(&Pt1, &Pt2);
  61.  
  62.     /* Should not change CrvLeft/Right only Crv1/2: */
  63.     CagdMakeCrvsCompatible(&Crv1, &CrvLeft, TRUE, TRUE);
  64.     CagdMakeCrvsCompatible(&Crv2, &CrvRight, TRUE, TRUE);
  65.  
  66.     Ruled3 = CagdRuledSrf(Crv1, Crv2, CrvTop -> Order, CrvTop -> Length);
  67.     CagdCrvFree(Crv1);
  68.     CagdCrvFree(Crv2);
  69.  
  70.     /* The boolean sum is equal to Ruled1 + Ruled2 - Ruled3. This boolean    */
  71.     /* sum as computed is not exactly as defined in the literature for non   */
  72.     /* uniform Bsplines since the ruled surfaces are computed with uniform   */
  73.     /* distribution along the other axis even if it is non uniform.         */
  74.     if (CrvRight -> GType == CAGD_CBSPLINE_TYPE) {
  75.     Srf = BspSrfNew(Ruled1 -> ULength, Ruled1 -> VLength,
  76.             Ruled1 -> UOrder, Ruled1 -> VOrder, Ruled1 -> PType);
  77.     IritFree((VoidPtr) Srf -> UKnotVector);
  78.     Srf -> UKnotVector = BspKnotCopy(CrvLeft -> KnotVector,
  79.                      CrvLeft -> Length + CrvLeft -> Order);
  80.     IritFree((VoidPtr) Srf -> VKnotVector);
  81.     Srf -> VKnotVector = BspKnotCopy(CrvTop -> KnotVector,
  82.                      CrvTop -> Length + CrvTop -> Order);
  83.     }
  84.     else if (CrvRight -> GType == CAGD_CBEZIER_TYPE)
  85.     Srf = BzrSrfNew(Ruled1 -> ULength, Ruled1 -> VLength, Ruled1 -> PType);
  86.     else
  87.     FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  88.     SrfPoints = Srf -> Points;
  89.  
  90.     Ruled1Pts = Ruled1 -> Points;
  91.     Ruled2Pts = Ruled2 -> Points;
  92.     Ruled3Pts = Ruled3 -> Points;
  93.  
  94.     for (i = !CAGD_IS_RATIONAL_SRF(Srf);
  95.      i <= CAGD_NUM_OF_PT_COORD(Srf -> PType);
  96.      i++) {
  97.     CagdRType
  98.         *Ruled1PtsPtr = Ruled1Pts[i],
  99.         *Ruled2PtsPtr = Ruled2Pts[i],
  100.         *Ruled3PtsPtr = Ruled3Pts[i],
  101.         *SrfPointsPtr = SrfPoints[i];
  102.  
  103.      for (j = Srf -> ULength * Srf -> VLength; j > 0; j--)
  104.          *SrfPointsPtr++ =
  105.          *Ruled1PtsPtr++ + *Ruled2PtsPtr++ - *Ruled3PtsPtr++;
  106.     }
  107.  
  108.     CagdSrfFree(Ruled1);
  109.     CagdSrfFree(Ruled2);
  110.     CagdSrfFree(Ruled3);
  111.  
  112.     return Srf;
  113. }
  114.  
  115. /******************************************************************************
  116. * Constructs a boolean sum surface using the single boundary curve.          *
  117. *   The curve is split into four, equally spaced in parameter space, parts    *
  118. * which are used as the four curves to the above Bool sum.              *
  119. ******************************************************************************/
  120. CagdSrfStruct *CagdOneBoolSumSrf(CagdCrvStruct *BndryCrv)
  121. {
  122.     CagdRType TMin, TMax;
  123.     CagdCrvStruct *Crvs, *TCrv, *CrvLeft, *CrvRight, *CrvTop, *CrvBottom;
  124.     CagdSrfStruct *BoolSumSrf;
  125.  
  126.     BspCrvDomain(BndryCrv, &TMin, &TMax);
  127.  
  128.     Crvs = BspCrvSubdivAtParam(BndryCrv, TMin * 0.5 + TMax * 0.5);
  129.     CrvLeft = BspCrvSubdivAtParam(Crvs, TMin * 0.75 + TMax * 0.25);
  130.     CrvRight = BspCrvSubdivAtParam(Crvs -> Pnext, TMin * 0.25 + TMax * 0.75);
  131.  
  132.     CagdCrvFreeList(Crvs);
  133.  
  134.     CrvBottom = CrvLeft -> Pnext;
  135.     CrvLeft -> Pnext = NULL;
  136.     CrvTop = CrvRight -> Pnext;
  137.     CrvRight -> Pnext = NULL;
  138.  
  139.     /* Reverse CrvBottom and CrvLeft: */
  140.     TCrv = CagdCrvReverse(CrvTop);
  141.     CagdCrvFree(CrvTop);
  142.     CrvTop = TCrv;
  143.  
  144.     TCrv = CagdCrvReverse(CrvRight);
  145.     CagdCrvFree(CrvRight);
  146.     CrvRight = TCrv;
  147.  
  148.     BoolSumSrf = CagdBoolSumSrf(CrvLeft, CrvRight, CrvTop, CrvBottom);
  149.  
  150.     CagdCrvFree(CrvTop);
  151.     CagdCrvFree(CrvRight);
  152.     CagdCrvFree(CrvBottom);
  153.     CagdCrvFree(CrvLeft);
  154.  
  155.     return BoolSumSrf;
  156. }
  157.